#include <iostream>
#include <fstream>
#include <thread>
#include <chrono>
#include <cstring>
#include "log.h"

using namespace std;
#define LOG_NAME_LEN 256
// 提前声明 verifyLogFile 函数
bool verifyLogFile(const string& filename, const vector<string>& expectedLines);
// 清理测试目录
void cleanTestDir() {
    system("rm -rf ./test_log && mkdir -p ./test_log");
}

// 测试同步日志写入
bool testSyncLogging() {
    cleanTestDir();
    Log::Instance()->init(1, "./test_log", ".log", 0);

    Log::Instance()->write(1, "Sync log test: %s", "hello world");
    Log::Instance()->write(3, "Error log test: %d", 42);

    Log::Instance()->flush();
    //Log::Instance()->~Log(); // 手动析构（测试用）

    time_t now = time(nullptr);
    struct tm t = *localtime(&now);
    char filename[LOG_NAME_LEN];
    snprintf(filename, LOG_NAME_LEN, "./test_log/%04d_%02d_%02d.log", 
             t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);

    vector<string> expected = {
        "[info] : Sync log test: hello world",
        "[error]: Error log test: 42"
    };

    return verifyLogFile(filename, expected);
}

// 测试异步日志写入
bool testAsyncLogging() {
    cleanTestDir();
    Log::Instance()->init(1, "./test_log", ".log", 100);

    for (int i = 0; i < 10; ++i) {
        Log::Instance()->write(1, "Async log %d", i);
    }

    Log::Instance()->flush();
    this_thread::sleep_for(chrono::milliseconds(200));
    //Log::Instance()->~Log();

    time_t now = time(nullptr);
    struct tm t = *localtime(&now);
    char filename[LOG_NAME_LEN];
    snprintf(filename, LOG_NAME_LEN, "./test_log/%04d_%02d_%02d.log", 
             t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);

    vector<string> expected;
    for (int i = 0; i < 10; ++i) {
        expected.push_back("[info] : Async log " + to_string(i));
    }

    return verifyLogFile(filename, expected);
}

// 验证日志文件内容
bool verifyLogFile(const string& filename, const vector<string>& expectedLines) {
    ifstream file(filename);
    if (!file.is_open()) {
        cerr << "Log file not found: " << filename << endl;
        return false;
    }

    string line;
    vector<string> actualLines;
    while (getline(file, line)) {
        actualLines.push_back(line);
    }
    file.close();

    if (actualLines.size() != expectedLines.size()) {
        cerr << "Line count mismatch: expected " << expectedLines.size() 
             << ", actual " << actualLines.size() << endl;
        return false;
    }

    for (size_t i = 0; i < expectedLines.size(); ++i) {
        if (actualLines[i].find(expectedLines[i]) == string::npos) {
            cerr << "Line " << i+1 << " mismatch: expected \"" << expectedLines[i] 
                 << "\", actual \"" << actualLines[i] << "\"" << endl;
            return false;
        }
    }
    return true;
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        cerr << "Usage: " << argv[0] << " [-0|-1]" << endl;
        cerr << "  -0: Test synchronous logging" << endl;
        cerr << "  -1: Test asynchronous logging" << endl;
        return 1;
    }

    bool result = false;

    if (strcmp(argv[1], "-0") == 0) {
        cout << "=== Testing Synchronous Logging ===" << endl;
        result = testSyncLogging();
    } else if (strcmp(argv[1], "-1") == 0) {
        cout << "=== Testing Asynchronous Logging ===" << endl;
        result = testAsyncLogging();
    } else {
        cerr << "Invalid argument: " << argv[1] << endl;
        return 1;
    }

    if (result) {
        cout << "Test passed." << endl;
        return 0;
    } else {
        cout << "Test failed." << endl;
        return 1;
    }
}